package com.hoas.distributedlock.spring.autoconfigure;

import com.hoas.distributedlock.core.DisributedLockStrategy;
import com.hoas.distributedlock.spring.SpringRedisLockStrategy;
import com.hoas.distributedlock.strategy.redis.RedisLockStrategy;
import com.hoas.distributedlock.strategy.zookeeper.ZookeeperLockStrategy;
import org.I0Itec.zkclient.ZkClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.JedisPool;

@Configuration
public class DistributedLockAutoConfigure {

    @Bean
    @ConfigurationProperties("hoas.distributedlock")
    public DistributedLockProperties distributedLockProperties() {
        return new DistributedLockProperties();
    }

    @Bean
    @ConditionalOnClass(JedisPool.class)
    @ConditionalOnProperty(value = "hoas.distributedlock.lockStrategy", havingValue="redis", matchIfMissing = true)
    public DisributedLockStrategy redisLockStrategy(DistributedLockProperties properties, JedisPool jedisPool) {
        return new RedisLockStrategy("redis", jedisPool, getSuggestPrefix(properties));
    }

    @Bean
    @ConditionalOnClass(RedisTemplate.class)
    @ConditionalOnProperty(value = "hoas.distributedlock.lockStrategy", havingValue="spring-redis", matchIfMissing = true)
    public DisributedLockStrategy spingRedisLockStrategy(DistributedLockProperties properties, RedisTemplate redisTemplate) {
        return new SpringRedisLockStrategy("sprng-redis", redisTemplate, getSuggestPrefix(properties));
    }

    @Bean
    @ConditionalOnClass(ZkClient.class)
    @ConditionalOnProperty(value = "hoas.distributedlock.lockStrategy", havingValue="zookeeper", matchIfMissing = true)
    public DisributedLockStrategy zookeeperLockStrategy(DistributedLockProperties properties, ZkClient zkClient) {
        return new ZookeeperLockStrategy("zookeeper", zkClient, getSuggestPrefix(properties));
    }

    private String getSuggestPrefix(DistributedLockProperties properties) {
        String prefix = properties.getPrefix();
        if (prefix == null) {
            prefix = "disributedlock";
        }

        if (properties.getNamespace() != null && properties.getNamespace().length() > 0 ) {
            prefix = prefix + ":" + properties.getNamespace();
        }

        if (properties.getAppName() != null && properties.getAppName().length() > 0 ) {
            prefix = prefix + ":" + properties.getAppName();
        }

        return prefix;

    }

}
